package com.ld.security.common.shiro;


import com.ld.security.common.shiro.config.ShiroProperties;
import com.ld.security.common.shiro.constants.ShiroCacheConstants;
import com.ld.security.common.shiro.realm.*;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SubjectFactory;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * 抽象
 */
@Configuration
@ComponentScan("com.ld.security.common.shiro")
@EnableConfigurationProperties(ShiroProperties.class)
public class ShiroWebConfiguration extends AbstractShiroConfiguration {

    @Autowired(required = false)
    private List<Realm> realms;


    @Autowired(required = false)
    private List<SessionListener> listeners;


    @Autowired
    ShiroProperties shiroProperties;

    @Bean
    @ConditionalOnClass
    @Override
    public PassowrdMatcher passowrdCredentialsMatcher() {
        return super.passowrdCredentialsMatcher();
    }


    @Override
    public List<Realm> realms() {

        for (Realm realm : realms) {
            if(realm instanceof  BaseAuthRealm){
                BaseAuthRealm authRealm =(BaseAuthRealm) realm;
                authRealm.setCacheManager(cacheManager());
                authRealm.setShiroProperties(shiroProperties);
                authRealm.setCredentialsMatcher(passowrdCredentialsMatcher());
            }
        }
        return realms;
    }


    @Bean
    @ConditionalOnClass
    public JwtRealm jwtRealm(){
        return new JwtRealm();
    }

    @ConditionalOnClass
    @Bean
    public HmacRealm hmacRealm(){
        return new HmacRealm();
    }

    @ConditionalOnClass
    @Bean
    public PasswordRealm PasswordRealm(){
        return new PasswordRealm();
    }



    @Bean
    @ConditionalOnClass
    @Override
    public SessionDAO getSessionDAO() {
        ShiroProperties shiroProperties = shiroProperties();
        if(shiroProperties.getCache().isSessionCache()){
            if(shiroProperties.getCache().getCacheType().equals(ShiroCacheConstants.cacheRedis)){
                RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
                redisSessionDAO.setRedisManager(redisManager());
                redisSessionDAO.setKeyPrefix(shiroProperties.getCache().getSessionCacheName());
                return redisSessionDAO;
            }else{
                return  super.getSessionDAO();
            }
        }else{
            return  super.getSessionDAO();
        }
    }

    @Bean
    @ConditionalOnClass
    @Override
    public ShiroProperties shiroProperties() {
        return super.shiroProperties();
    }



//    @Bean
//    @ConditionalOnClass
//    public JwtAuthcFilter JwtAuthcFilter() {
//        return new JwtAuthcFilter(shiroProperties().getJwt());
//    }

    @Bean
    @ConditionalOnClass
    @Override
    public SubjectFactory subjectFactory() {
        return super.subjectFactory();
    }



    @Bean
    @ConditionalOnClass
    @Override
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        return super.shiroFilterFactoryBean();
    }


    @Bean
    @ConditionalOnClass
    @Override
    public SecurityManager securityManager() {
        return super.securityManager();
    }

    @Bean
    @ConditionalOnClass
    @Override
    public List<SessionListener> getSessionListeners() {
        if(listeners == null){
            return super.getSessionListeners();
        }else{
            return listeners;
        }

    }

    @Bean
    @ConditionalOnClass
    @Override
    public SessionManager sessionManager() {
        return super.sessionManager();
    }

    @Bean
    @ConditionalOnClass
    @Override
    public RememberMeManager rememberMeManager() {
        return super.rememberMeManager();
    }



    @Bean
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();

        redisManager.setExpire(shiroProperties().getCache().getCacheExpire());
        // 配置缓存过期时间
        // redisManager.setPassword(password)
        return redisManager;
    }


    @Override
    @Bean
    public CacheManager cacheManager() {
        if(shiroProperties.getCache().getCacheType().equals(ShiroCacheConstants.cacheRedis)){
            RedisCacheManager redisCacheManager = new RedisCacheManager();
            redisCacheManager.setRedisManager(redisManager());
            return redisCacheManager;
        }else {
            return super.cacheManager();
        }

    }




}
